#pragma once

#ifndef _I_DROPLET
#define _I_DROPLET

#ifdef _WIN32
#include "inttypes.h"
#elif
#include <inttypes.h>	// inttypes.h is included in UNIX systems
#endif

#ifdef D_SIM_LIB

#include "btBulletDynamicsCommon.h"
#include "DropletSimGlobals.h"
#include "DropletDataStructs.h"

#endif

#include <cstdlib>
#include <utility>

#ifdef D_SIM_LIB

class IDroplet
{
private :

	ObjectPhysicsData *objPhysics;
	DropletActuatorData *actData;
	DropletSensorData *senseData;
	DropletCommData *commData;
	DropletCompData *compData;

	/* NOTE : These friend functions are meant for use by the simulator backend ONLY.
	 * DO NOT USE THESE IN ANY CODE WRITTEN FOR A CLASS DERIVED FROM IDroplet!!!
	 */
	friend void AccessPhysicsData(IDroplet *pDroplet, ObjectPhysicsData **objPhysics)
	{
		*objPhysics = pDroplet->objPhysics;
	}

	friend void AccessActuatorData(IDroplet *pDroplet, DropletActuatorData **actData)
	{
		*actData = pDroplet->actData;
	}

	friend void AccessSensorData(IDroplet *pDroplet, DropletSensorData **senseData)
	{
		*senseData = pDroplet->senseData;
	}

	friend void AccessCommData(IDroplet *pDroplet, DropletCommData **commData)
	{
		*commData = pDroplet->commData;
	}

	friend void AccessCompData(IDroplet *pDroplet, DropletCompData **compData)
	{
		*compData = pDroplet->compData;
	}

protected :
#endif	// D_SIM_LIB

// Droplet Subsystems Setup Functions
	void ResetAllSystems(void);
	void ResetRGBLED(void);
	void ResetIRLED(void);
	void ResetIRSensor(void);
	void ResetRGBSensor(void);
	void ResetMotors(void);

	uint16_t GetDropletID(void);

	void SeedRandom(int32_t seed);
	uint8_t GetRandom(void);

// Droplet Actuator Subsystem Functions
	void Rotate(uint8_t dur, turn_direction dir);
	void Move(uint8_t dur, move_direction dir);
	void SetRGB(uint8_t r, uint8_t g, uint8_t b);
	void CancelRotate(void);
	void CancelMove(void);

	/* The following two functions return 0 if the droplet is not moving/rotating
	 * and some integer > 0, otherwise.
	 */
	uint8_t IsRotating(void);
	uint8_t IsMoving(void);

// TODO : Droplet Sensor Subsystem Functions
	void GetRGB(uint8_t *r, uint8_t *g, uint8_t *b);

// TODO : Droplet Communication Subsystem Functions

#ifdef D_SIM_LIB
public :
	
// Constructor and Destructor
	IDroplet(ObjectPhysicsData *objPhysics);
	virtual ~IDroplet();
		
	DS_RESULT _InitPhysics(
		SimPhysicsData *simPhysics,
		std::pair<float, float> startPosition,
		float startAngle);

// Droplet Simulator Functions to be overridden
	virtual void DropletInit(void);
	virtual void DropletMainLoop(void);
};
#endif	// D_SIM_LIB

#endif